package com.du.config;

import com.du.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author djg
 * @date 2020/11/23
 * bean的生命周期 ：bean创建——》初始化——》销毁的过程
 * 容器可以管理Bean的生命周期
 * 我们可以自定义初始化和销毁方法，容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
 *
 * 构造（对象创建）
 *      单实例：在容器启动的时候创建对象
 *      多实例：在每次获取对象的时候创建
 *
 * 初始化前：BeanPostProcessor.postProcessBeforeInitialization()
 * 初始化：
 *      对象创建完成，并赋值好，调用初始化方法。。。
 * 初始化后：BeanPostProcessor.postProcessAfterInitialization()
 *
 * 销毁：
 *      单实例：容器关闭的时候
 *      多实例：容器不会管理这个bean，容器不会调用销毁方法
 *
 * 遍历得到容器中的所有BeanPostProcessor，挨个执行beforeInitialization，一旦返回null，跳出for循环，不会执行后面的BeanPostProcessor
 *
 * BeanPostProcessor原理：
 * populateBean(beanName, mbd, instanceWrapper);给Bean进行属性赋值的
 * initializeBean(beanName, exposedObject, mbd); 初始化
 * {
 *  applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 *  invokeInitMethods(beanName, wrappedBean, mbd); 执行自定义初始化
 *  applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 * }
 *
 * Spring底层对于BeanPostProcessor的使用：
 *      Bean赋值，注入其他组件，@Autowired，生命周期注解功能，@Async等都是使用BeanPostProcessor完成的
 *
 *
 *
 * 1、指定初始化和销毁方法
 *      1.1 XML的方式 指定init-method 和 destroy-method方法
 *      1.2 Configuration方式通过@Bean注解中指定initMethod和destroyMethod方法
 * 2、通过让Bean实现InitializingBean（定义初始化逻辑）,DisposableBean(定义销毁逻辑)
 * 3、可以使用JSR250
 *      @PostConstruct: 在bean创建完成并且属性赋值完成，来执行初始化方法
 *      @PreDestroy: 在容器销毁Bean之前通知我们进行清理工作
 * 4、BeanPostProcessor接口:bean的后置处理器
 *      在Bean初始化前后进行一些处理工作
 *      postProcessBeforeInitialization：在初始化之前工作
 *      postProcessAfterInitialization：在初始化之后工作
 *
 */
@Configuration
@ComponentScan("com.du.bean")
public class MainConfigLifeCycle {

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car() {
        return new Car();
    }
}
